-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local validate = require 'mc.validate'
local utils = require 'mc.utils'
local mdb = require 'mc.mdb'

local GPU = {}

---@class GPU.PrimaryGPUTemperatureCelsius
---@field PrimaryGPUTemperatureCelsius number
local TPrimaryGPUTemperatureCelsius = {}
TPrimaryGPUTemperatureCelsius.__index = TPrimaryGPUTemperatureCelsius
TPrimaryGPUTemperatureCelsius.group = {}

local function TPrimaryGPUTemperatureCelsius_from_obj(obj)
    return setmetatable(obj, TPrimaryGPUTemperatureCelsius)
end

function TPrimaryGPUTemperatureCelsius.new(PrimaryGPUTemperatureCelsius)
    return
        TPrimaryGPUTemperatureCelsius_from_obj({PrimaryGPUTemperatureCelsius = PrimaryGPUTemperatureCelsius or 32768})
end
---@param obj GPU.PrimaryGPUTemperatureCelsius
function TPrimaryGPUTemperatureCelsius:init_from_obj(obj)
    self.PrimaryGPUTemperatureCelsius = obj.PrimaryGPUTemperatureCelsius or 32768
end

function TPrimaryGPUTemperatureCelsius:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TPrimaryGPUTemperatureCelsius.group)
end

TPrimaryGPUTemperatureCelsius.from_obj = TPrimaryGPUTemperatureCelsius_from_obj

TPrimaryGPUTemperatureCelsius.proto_property = {'PrimaryGPUTemperatureCelsius'}

TPrimaryGPUTemperatureCelsius.default = {0}

TPrimaryGPUTemperatureCelsius.struct = {{name = 'PrimaryGPUTemperatureCelsius', is_array = false, struct = nil}}

function TPrimaryGPUTemperatureCelsius:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'PrimaryGPUTemperatureCelsius', self.PrimaryGPUTemperatureCelsius, 'double', true, errs,
        need_convert)

    TPrimaryGPUTemperatureCelsius:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TPrimaryGPUTemperatureCelsius.proto_property, errs, need_convert)
    return self
end

function TPrimaryGPUTemperatureCelsius:unpack(_)
    return self.PrimaryGPUTemperatureCelsius
end

GPU.PrimaryGPUTemperatureCelsius = TPrimaryGPUTemperatureCelsius

---@class GPU.MemoryUtilization
---@field MemoryUtilization integer
local TMemoryUtilization = {}
TMemoryUtilization.__index = TMemoryUtilization
TMemoryUtilization.group = {}

local function TMemoryUtilization_from_obj(obj)
    return setmetatable(obj, TMemoryUtilization)
end

function TMemoryUtilization.new(MemoryUtilization)
    return TMemoryUtilization_from_obj({MemoryUtilization = MemoryUtilization})
end
---@param obj GPU.MemoryUtilization
function TMemoryUtilization:init_from_obj(obj)
    self.MemoryUtilization = obj.MemoryUtilization
end

function TMemoryUtilization:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TMemoryUtilization.group)
end

TMemoryUtilization.from_obj = TMemoryUtilization_from_obj

TMemoryUtilization.proto_property = {'MemoryUtilization'}

TMemoryUtilization.default = {0}

TMemoryUtilization.struct = {{name = 'MemoryUtilization', is_array = false, struct = nil}}

function TMemoryUtilization:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'MemoryUtilization', self.MemoryUtilization, 'uint16', true, errs, need_convert)

    TMemoryUtilization:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TMemoryUtilization.proto_property, errs, need_convert)
    return self
end

function TMemoryUtilization:unpack(_)
    return self.MemoryUtilization
end

GPU.MemoryUtilization = TMemoryUtilization

---@class GPU.GPUUtilization
---@field GPUUtilization integer
local TGPUUtilization = {}
TGPUUtilization.__index = TGPUUtilization
TGPUUtilization.group = {}

local function TGPUUtilization_from_obj(obj)
    return setmetatable(obj, TGPUUtilization)
end

function TGPUUtilization.new(GPUUtilization)
    return TGPUUtilization_from_obj({GPUUtilization = GPUUtilization})
end
---@param obj GPU.GPUUtilization
function TGPUUtilization:init_from_obj(obj)
    self.GPUUtilization = obj.GPUUtilization
end

function TGPUUtilization:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TGPUUtilization.group)
end

TGPUUtilization.from_obj = TGPUUtilization_from_obj

TGPUUtilization.proto_property = {'GPUUtilization'}

TGPUUtilization.default = {0}

TGPUUtilization.struct = {{name = 'GPUUtilization', is_array = false, struct = nil}}

function TGPUUtilization:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'GPUUtilization', self.GPUUtilization, 'uint16', true, errs, need_convert)

    TGPUUtilization:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TGPUUtilization.proto_property, errs, need_convert)
    return self
end

function TGPUUtilization:unpack(_)
    return self.GPUUtilization
end

GPU.GPUUtilization = TGPUUtilization

---@class GPU.SubDeviceID
---@field SubDeviceID integer
local TSubDeviceID = {}
TSubDeviceID.__index = TSubDeviceID
TSubDeviceID.group = {}

local function TSubDeviceID_from_obj(obj)
    return setmetatable(obj, TSubDeviceID)
end

function TSubDeviceID.new(SubDeviceID)
    return TSubDeviceID_from_obj({SubDeviceID = SubDeviceID})
end
---@param obj GPU.SubDeviceID
function TSubDeviceID:init_from_obj(obj)
    self.SubDeviceID = obj.SubDeviceID
end

function TSubDeviceID:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSubDeviceID.group)
end

TSubDeviceID.from_obj = TSubDeviceID_from_obj

TSubDeviceID.proto_property = {'SubDeviceID'}

TSubDeviceID.default = {0}

TSubDeviceID.struct = {{name = 'SubDeviceID', is_array = false, struct = nil}}

function TSubDeviceID:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'SubDeviceID', self.SubDeviceID, 'uint16', true, errs, need_convert)

    TSubDeviceID:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSubDeviceID.proto_property, errs, need_convert)
    return self
end

function TSubDeviceID:unpack(_)
    return self.SubDeviceID
end

GPU.SubDeviceID = TSubDeviceID

---@class GPU.SubVendorID
---@field SubVendorID integer
local TSubVendorID = {}
TSubVendorID.__index = TSubVendorID
TSubVendorID.group = {}

local function TSubVendorID_from_obj(obj)
    return setmetatable(obj, TSubVendorID)
end

function TSubVendorID.new(SubVendorID)
    return TSubVendorID_from_obj({SubVendorID = SubVendorID})
end
---@param obj GPU.SubVendorID
function TSubVendorID:init_from_obj(obj)
    self.SubVendorID = obj.SubVendorID
end

function TSubVendorID:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSubVendorID.group)
end

TSubVendorID.from_obj = TSubVendorID_from_obj

TSubVendorID.proto_property = {'SubVendorID'}

TSubVendorID.default = {0}

TSubVendorID.struct = {{name = 'SubVendorID', is_array = false, struct = nil}}

function TSubVendorID:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'SubVendorID', self.SubVendorID, 'uint16', true, errs, need_convert)

    TSubVendorID:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSubVendorID.proto_property, errs, need_convert)
    return self
end

function TSubVendorID:unpack(_)
    return self.SubVendorID
end

GPU.SubVendorID = TSubVendorID

---@class GPU.DeviceID
---@field DeviceID integer
local TDeviceID = {}
TDeviceID.__index = TDeviceID
TDeviceID.group = {}

local function TDeviceID_from_obj(obj)
    return setmetatable(obj, TDeviceID)
end

function TDeviceID.new(DeviceID)
    return TDeviceID_from_obj({DeviceID = DeviceID})
end
---@param obj GPU.DeviceID
function TDeviceID:init_from_obj(obj)
    self.DeviceID = obj.DeviceID
end

function TDeviceID:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TDeviceID.group)
end

TDeviceID.from_obj = TDeviceID_from_obj

TDeviceID.proto_property = {'DeviceID'}

TDeviceID.default = {0}

TDeviceID.struct = {{name = 'DeviceID', is_array = false, struct = nil}}

function TDeviceID:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'DeviceID', self.DeviceID, 'uint16', true, errs, need_convert)

    TDeviceID:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TDeviceID.proto_property, errs, need_convert)
    return self
end

function TDeviceID:unpack(_)
    return self.DeviceID
end

GPU.DeviceID = TDeviceID

---@class GPU.VendorID
---@field VendorID integer
local TVendorID = {}
TVendorID.__index = TVendorID
TVendorID.group = {}

local function TVendorID_from_obj(obj)
    return setmetatable(obj, TVendorID)
end

function TVendorID.new(VendorID)
    return TVendorID_from_obj({VendorID = VendorID})
end
---@param obj GPU.VendorID
function TVendorID:init_from_obj(obj)
    self.VendorID = obj.VendorID
end

function TVendorID:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TVendorID.group)
end

TVendorID.from_obj = TVendorID_from_obj

TVendorID.proto_property = {'VendorID'}

TVendorID.default = {0}

TVendorID.struct = {{name = 'VendorID', is_array = false, struct = nil}}

function TVendorID:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'VendorID', self.VendorID, 'uint16', true, errs, need_convert)

    TVendorID:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TVendorID.proto_property, errs, need_convert)
    return self
end

function TVendorID:unpack(_)
    return self.VendorID
end

GPU.VendorID = TVendorID

---@class GPU.Slot
---@field Slot string
local TSlot = {}
TSlot.__index = TSlot
TSlot.group = {}

local function TSlot_from_obj(obj)
    return setmetatable(obj, TSlot)
end

function TSlot.new(Slot)
    return TSlot_from_obj({Slot = Slot})
end
---@param obj GPU.Slot
function TSlot:init_from_obj(obj)
    self.Slot = obj.Slot
end

function TSlot:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSlot.group)
end

TSlot.from_obj = TSlot_from_obj

TSlot.proto_property = {'Slot'}

TSlot.default = {''}

TSlot.struct = {{name = 'Slot', is_array = false, struct = nil}}

function TSlot:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'Slot', self.Slot, 'string', true, errs, need_convert)

    TSlot:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSlot.proto_property, errs, need_convert)
    return self
end

function TSlot:unpack(_)
    return self.Slot
end

GPU.Slot = TSlot

---@class GPU.UUID
---@field UUID string
local TUUID = {}
TUUID.__index = TUUID
TUUID.group = {}

local function TUUID_from_obj(obj)
    return setmetatable(obj, TUUID)
end

function TUUID.new(UUID)
    return TUUID_from_obj({UUID = UUID})
end
---@param obj GPU.UUID
function TUUID:init_from_obj(obj)
    self.UUID = obj.UUID
end

function TUUID:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TUUID.group)
end

TUUID.from_obj = TUUID_from_obj

TUUID.proto_property = {'UUID'}

TUUID.default = {''}

TUUID.struct = {{name = 'UUID', is_array = false, struct = nil}}

function TUUID:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'UUID', self.UUID, 'string', true, errs, need_convert)

    TUUID:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TUUID.proto_property, errs, need_convert)
    return self
end

function TUUID:unpack(_)
    return self.UUID
end

GPU.UUID = TUUID

---@class GPU.BuildDate
---@field BuildDate string
local TBuildDate = {}
TBuildDate.__index = TBuildDate
TBuildDate.group = {}

local function TBuildDate_from_obj(obj)
    return setmetatable(obj, TBuildDate)
end

function TBuildDate.new(BuildDate)
    return TBuildDate_from_obj({BuildDate = BuildDate})
end
---@param obj GPU.BuildDate
function TBuildDate:init_from_obj(obj)
    self.BuildDate = obj.BuildDate
end

function TBuildDate:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TBuildDate.group)
end

TBuildDate.from_obj = TBuildDate_from_obj

TBuildDate.proto_property = {'BuildDate'}

TBuildDate.default = {''}

TBuildDate.struct = {{name = 'BuildDate', is_array = false, struct = nil}}

function TBuildDate:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'BuildDate', self.BuildDate, 'string', true, errs, need_convert)

    TBuildDate:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TBuildDate.proto_property, errs, need_convert)
    return self
end

function TBuildDate:unpack(_)
    return self.BuildDate
end

GPU.BuildDate = TBuildDate

---@class GPU.MemoryPartNumber
---@field MemoryPartNumber string
local TMemoryPartNumber = {}
TMemoryPartNumber.__index = TMemoryPartNumber
TMemoryPartNumber.group = {}

local function TMemoryPartNumber_from_obj(obj)
    return setmetatable(obj, TMemoryPartNumber)
end

function TMemoryPartNumber.new(MemoryPartNumber)
    return TMemoryPartNumber_from_obj({MemoryPartNumber = MemoryPartNumber})
end
---@param obj GPU.MemoryPartNumber
function TMemoryPartNumber:init_from_obj(obj)
    self.MemoryPartNumber = obj.MemoryPartNumber
end

function TMemoryPartNumber:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TMemoryPartNumber.group)
end

TMemoryPartNumber.from_obj = TMemoryPartNumber_from_obj

TMemoryPartNumber.proto_property = {'MemoryPartNumber'}

TMemoryPartNumber.default = {''}

TMemoryPartNumber.struct = {{name = 'MemoryPartNumber', is_array = false, struct = nil}}

function TMemoryPartNumber:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'MemoryPartNumber', self.MemoryPartNumber, 'string', true, errs, need_convert)

    TMemoryPartNumber:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TMemoryPartNumber.proto_property, errs, need_convert)
    return self
end

function TMemoryPartNumber:unpack(_)
    return self.MemoryPartNumber
end

GPU.MemoryPartNumber = TMemoryPartNumber

---@class GPU.MemoryVendor
---@field MemoryVendor string
local TMemoryVendor = {}
TMemoryVendor.__index = TMemoryVendor
TMemoryVendor.group = {}

local function TMemoryVendor_from_obj(obj)
    return setmetatable(obj, TMemoryVendor)
end

function TMemoryVendor.new(MemoryVendor)
    return TMemoryVendor_from_obj({MemoryVendor = MemoryVendor})
end
---@param obj GPU.MemoryVendor
function TMemoryVendor:init_from_obj(obj)
    self.MemoryVendor = obj.MemoryVendor
end

function TMemoryVendor:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TMemoryVendor.group)
end

TMemoryVendor.from_obj = TMemoryVendor_from_obj

TMemoryVendor.proto_property = {'MemoryVendor'}

TMemoryVendor.default = {''}

TMemoryVendor.struct = {{name = 'MemoryVendor', is_array = false, struct = nil}}

function TMemoryVendor:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'MemoryVendor', self.MemoryVendor, 'string', true, errs, need_convert)

    TMemoryVendor:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TMemoryVendor.proto_property, errs, need_convert)
    return self
end

function TMemoryVendor:unpack(_)
    return self.MemoryVendor
end

GPU.MemoryVendor = TMemoryVendor

---@class GPU.BoardPartNumber
---@field BoardPartNumber string
local TBoardPartNumber = {}
TBoardPartNumber.__index = TBoardPartNumber
TBoardPartNumber.group = {}

local function TBoardPartNumber_from_obj(obj)
    return setmetatable(obj, TBoardPartNumber)
end

function TBoardPartNumber.new(BoardPartNumber)
    return TBoardPartNumber_from_obj({BoardPartNumber = BoardPartNumber})
end
---@param obj GPU.BoardPartNumber
function TBoardPartNumber:init_from_obj(obj)
    self.BoardPartNumber = obj.BoardPartNumber
end

function TBoardPartNumber:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TBoardPartNumber.group)
end

TBoardPartNumber.from_obj = TBoardPartNumber_from_obj

TBoardPartNumber.proto_property = {'BoardPartNumber'}

TBoardPartNumber.default = {''}

TBoardPartNumber.struct = {{name = 'BoardPartNumber', is_array = false, struct = nil}}

function TBoardPartNumber:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'BoardPartNumber', self.BoardPartNumber, 'string', true, errs, need_convert)

    TBoardPartNumber:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TBoardPartNumber.proto_property, errs, need_convert)
    return self
end

function TBoardPartNumber:unpack(_)
    return self.BoardPartNumber
end

GPU.BoardPartNumber = TBoardPartNumber

---@class GPU.InfoRomVersion
---@field InfoRomVersion string
local TInfoRomVersion = {}
TInfoRomVersion.__index = TInfoRomVersion
TInfoRomVersion.group = {}

local function TInfoRomVersion_from_obj(obj)
    return setmetatable(obj, TInfoRomVersion)
end

function TInfoRomVersion.new(InfoRomVersion)
    return TInfoRomVersion_from_obj({InfoRomVersion = InfoRomVersion})
end
---@param obj GPU.InfoRomVersion
function TInfoRomVersion:init_from_obj(obj)
    self.InfoRomVersion = obj.InfoRomVersion
end

function TInfoRomVersion:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TInfoRomVersion.group)
end

TInfoRomVersion.from_obj = TInfoRomVersion_from_obj

TInfoRomVersion.proto_property = {'InfoRomVersion'}

TInfoRomVersion.default = {''}

TInfoRomVersion.struct = {{name = 'InfoRomVersion', is_array = false, struct = nil}}

function TInfoRomVersion:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'InfoRomVersion', self.InfoRomVersion, 'string', true, errs, need_convert)

    TInfoRomVersion:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TInfoRomVersion.proto_property, errs, need_convert)
    return self
end

function TInfoRomVersion:unpack(_)
    return self.InfoRomVersion
end

GPU.InfoRomVersion = TInfoRomVersion

GPU.interface = mdb.register_interface('bmc.kepler.Systems.Processor.GPU', {
    InfoRomVersion = {'s', nil, true, nil, false},
    BoardPartNumber = {'s', {'EMIT_CHANGE'}, true, nil, false},
    MemoryVendor = {'s', {'EMIT_CHANGE'}, true, nil, false},
    MemoryPartNumber = {'s', {'EMIT_CHANGE'}, true, nil, false},
    BuildDate = {'s', {'EMIT_CHANGE'}, true, nil, false},
    UUID = {'s', {'EMIT_CHANGE'}, true, nil, false},
    Slot = {'s', nil, true, nil, false},
    VendorID = {'q', nil, true, nil, false},
    DeviceID = {'q', nil, true, nil, false},
    SubVendorID = {'q', nil, true, nil, false},
    SubDeviceID = {'q', nil, true, nil, false},
    GPUUtilization = {'q', nil, true, nil, false},
    MemoryUtilization = {'q', nil, true, nil, false},
    PrimaryGPUTemperatureCelsius = {'d', nil, true, 32768, false}
}, {}, {})

return GPU
